const now = window.performance && window.performance.now ?
    window.performance.now.bind(window.performance) :
    Date.now.bind(Date);

const raf = window.requestAnimationFrame ||
    window.mozRequestAnimationFrame ||
    window.webkitRequestAnimationFrame ||
    window.msRequestAnimationFrame;

const cancel = window.cancelAnimationFrame ||
    window.mozCancelAnimationFrame ||
    window.webkitCancelAnimationFrame ||
    window.msCancelAnimationFrame;

let linkElement;

/**
 * @const
 * @private
 * @name browser
 */
const browser = {
    /**
     * 获取当前时间（毫秒）。
     * @memberOf browser
     * @method
     * @return {number} 当前时间毫秒。
     */
    now,
    /**
     * 开启动画帧requestAnimationFrame调用。
     * @memberOf browser
     * @method
     * @param {FrameRequestCallback} fn 每帧重绘时调用的函数。
     * @return {Object} 返回包含取消当前动画帧调用方法的对象。
     */
    frame(fn) {
        const frame = raf(fn);
        return { cancel: () => cancel(frame) };
    },
    /**
     * 获取指定canvas图像源的图像数据。
     * @memberOf browser
     * @method
     * @param {CanvasImageSource} img canvas图像源。
     * @return {ImageData} 返回图像数据。
     */
    getImageData(img) {
        const canvas = window.document.createElement('canvas');
        const context = canvas.getContext('2d');
        if (!context) {
            throw new Error('failed to create canvas 2d context');
        }
        canvas.width = img.width;
        canvas.height = img.height;
        context.drawImage(img, 0, 0, img.width, img.height);
        return context.getImageData(0, 0, img.width, img.height);
    },
    /**
     * 相对路径转换为绝对路径。
     * @memberOf browser
     * @method
     * @param {string} path 相对路径。
     * @return {string} 返回绝对路径。
     */
    resolveURL(path) {
        if (!linkElement) linkElement = window.document.createElement('a');
        linkElement.href = path;
        return linkElement.href;
    },
    /**
     * cpu核心数。
     * @memberOf browser
     * @type {number}
     */
    hardwareConcurrency: window.navigator.hardwareConcurrency || 4,
    /**
     * 设备像素比。
     * @memberOf browser
     * @readonly
     * @type {number} 
     */
    get devicePixelRatio() { return window.devicePixelRatio; }
};

export {browser};